<?php
/**
 * Created by 项目.
 * User: xuguopeng
 * Date: 2019-11-27
 * Time: 10:31
 */

namespace app\api\service;


use app\api\model\Image;
use app\api\model\LinFile;
use app\api\model\System;
use app\lib\enum\ScopeEnum;
use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use think\Exception;
use app\api\model\User as UserModel;
use think\facade\Cache;

class UserToken extends Token
{
    protected $code;
    protected $wxAppId;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    function __construct($code)
    {
        $this->code = $code;
        $this->wxAppId = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(config('wx.login_url'),
            $this->wxAppId, $this->wxAppSecret, $this->code);
        $this->wxCodeUrl = sprintf(config('wx.code_url'),
            $this->wxAppId, $this->wxAppSecret);
    }

    public function get()
    {
        $wxResult = curl_get($this->wxLoginUrl);
        if (empty($wxResult)) {
            throw new Exception('获取session_key及openId时异常,微信内部错误');
        } else {
            $loginFail = array_key_exists('errcode', $wxResult);
            if ($loginFail) {
                $this->processLoginError($wxResult);
            } else {
                return $this->grantToken($wxResult);
            }
        }
    }

    /**
     * 1.拿到openid
     * 2.openid 是否已经存在
     * 3.如果存在则不处理，如果不存在，新增一条记录
     * 4.生成令牌,准备缓存数据,写入缓存
     * 5.把令牌传回客户端
     * key: 令牌
     * value wxResult uid scope
     */
    private function grantToken($wxResult)
    {
        $openid = $wxResult['openid'];
        $user = UserModel::getOpenId($openid);
        if ($user) {
            $uid = $user->id;
        } else {
            $uid = $this->newUser($openid);
        }
        $cacheValue = $this->properCacheValue($wxResult, $uid);
        $token = $this->saveToCache($cacheValue);
        return $token;
    }

    /**
     * @param $cacheValue 需要缓存的对象
     * @return string token
     * @throws TokenException 验证token 公用错误
     */
    private function saveToCache($cacheValue)
    {
        $key = $this->generateToken();
        $value = json_encode($cacheValue);
        $expire_in = config('setting.token_expire_in');
        $result = cache($key, $value, $expire_in);
        if (!$result) {
            throw new TokenException([
                'msg' => '服务器缓存异常',
                'errorCode' => 10005
            ]);
        }
        return $key;
    }

    /**
     * @param $wxResult 微信返回值
     * @param $uid 用户ID
     * @return mixed 权限数字
     */
    private function properCacheValue($wxResult, $uid)
    {
        $cacheValue = $wxResult;
        $cacheValue['uid'] = $uid;
        $cacheValue['scope'] = ScopeEnum::User;
        return $cacheValue;
    }

    /**
     * @param $openid
     * @return 用户ID
     */
    private function newUser($openid)
    {
        $user = UserModel::create([
            'openid' => $openid
        ]);
        return $user->id;
    }

    /**
     * @param $wxResult 微信返回信息
     * @throws WeChatException 微信公用返回错误信息类
     */
    private function processLoginError($wxResult)
    {
        throw new WeChatException([
            'msg' => $wxResult['errmsg'],
            'errorCode' => $wxResult['errcode']
        ]);
    }

    /**
     * 生成门店二维码
     */
    public function setStoreCode($store_id)
    {
        $access_token = Cache::get('access_token');
        if (!$access_token) {
            $jsonInfo = curl_get($this->wxCodeUrl);
            $access_token = $jsonInfo["access_token"];
            $expire_in = config('setting.token_expire_in');
            $result = cache('access_token', $access_token, $expire_in);
            if (!$result) {
                throw new TokenException([
                    'msg' => '服务器缓存异常',
                    'errorCode' => 10005
                ]);
            }
        }
        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $access_token;
        $data['scene'] = $store_id;
        $data['page'] = 'pages/user/yuezhifu';
        $data['width'] = 680;
        $name = 'store_' . $store_id;
        $res = https_post($url, json_encode($data));
        if (!file_exists('./qr/' . $name . '.png')) {
            $file = fopen('./qr/' . $name . '.png', "w");//打开文件准备写入
            fwrite($file, $res);//写入,$res为图片二进制内容
            fclose($file);//关闭
        }
    }


    /**
     * 获取用户的分享二维码
     */
    public function setCode($user_id)
    {
        $access_token = Cache::get('access_token');
        if (!$access_token) {
            $jsonInfo = curl_get($this->wxCodeUrl);
            $access_token = $jsonInfo["access_token"];
            $expire_in = config('setting.token_expire_in');
            $result = cache('access_token', $access_token, $expire_in);
            if (!$result) {
                throw new TokenException([
                    'msg' => '服务器缓存异常',
                    'errorCode' => 10005
                ]);
            }
        }
        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $access_token;
        $data['scene'] = $user_id;
        $data['width'] = 450;
        $name = 'user_' . $user_id;
        $res = https_post($url, json_encode($data));
        if ($res) {
            $jsonInfo = curl_get($this->wxCodeUrl);
            $access_token = $jsonInfo["access_token"];
            $expire_in = config('setting.token_expire_in');
            $result = cache('access_token', $access_token, $expire_in);
            if (!$result) {
                throw new TokenException([
                    'msg' => '服务器缓存异常',
                    'errorCode' => 10005
                ]);
            }
            $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $access_token;
            $data['scene'] = $user_id;
            $data['width'] = 450;
            $name = 'user_' . $user_id;
            $res = https_post($url, json_encode($data));
            $file = fopen('/www/wwwroot/xiledaojia.com/public/qr/' . $name . '.png', "w");//打开文件准备写入
            fwrite($file, $res);//写入,$res为图片二进制内容
            fclose($file);//关闭
            $filename = '/www/wwwroot/xiledaojia.com/public/static/invite.jpeg';

//            dump($filename);die();
            $image = \think\Image::open($filename); //要加水印的图片 两个字 array(445,360)
            $image->water('/www/wwwroot/xiledaojia.com/public/qr/' . $name . '.png', array(250, 500), 100)->save('/www/wwwroot/xiledaojia.com/public/qr/' . $name . '.png');//添加图片
        } else {
            $file = fopen('/www/wwwroot/xiledaojia.com/public/qr/' . $name . '.png', "w");//打开文件准备写入
            fwrite($file, $res);//写入,$res为图片二进制内容
            fclose($file);//关闭
            $system = System::where('id', 1)->find();
            $image = Image::where('id', $system['invite_img_id'])->find();
            $flie = LinFile::where('id', $image['file_id'])->find();
            $filename = '/www/wwwroot/xiledaojia.com/public/static/invite.jpeg';
            $image = \think\Image::open($filename); //要加水印的图片 两个字 array(445,360)
            $image->water('/www/wwwroot/xiledaojia.com/public/qr/' . $name . '.png', array(250, 500), 100)->save('/www/wwwroot/xiledaojia.com/public/qr/' . $name . '.png');//添加图片
        }

    }
}